#include "led.h"
#include "driver/ledc.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "freertos/event_groups.h"
#include "esp_log.h"

#define FULL_EV_BIT BIT0
#define EMPTY_EV_BIT BIT1

// 事件组
static EventGroupHandle_t ledc_event_handle;

// 中断下的 ledc完成事件
bool IRAM_ATTR ledc_finish_cb(const ledc_cb_param_t *param, void *user_arg)
{
    BaseType_t taskWoken;
    if (param->duty)
    {
        xEventGroupSetBitsFromISR(ledc_event_handle, FULL_EV_BIT, &taskWoken);
    }
    else
    {
        xEventGroupSetBitsFromISR(ledc_event_handle, EMPTY_EV_BIT, &taskWoken);
    }
    return taskWoken;
}

// 监听事件并重新执行任务
void fade_events_listener(void *param)
{
    EventBits_t ev;

    while (1)
    {
        // ESP_LOGI("TASK", "CHECK EVENT\n");
        // vTaskDelay(pdTICKS_TO_MS(500));
        ledc_cbs_t cbs = {
            .fade_cb = ledc_finish_cb,
        };
        ledc_cb_register(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, &cbs, NULL);
        ev = xEventGroupWaitBits(ledc_event_handle, FULL_EV_BIT | EMPTY_EV_BIT, pdTRUE, pdFALSE, pdMS_TO_TICKS(5000));
        if (ev & FULL_EV_BIT)
        {
            // ESP_LOGI("TASK", "Receive FULL EVENT\n");
            ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0, 2000);
            ledc_fade_start(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        }
        if (ev & EMPTY_EV_BIT)
        {
            // ESP_LOGI("TASK", "Receive EMPTY EVENT\n");
            ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 8191, 2000);
            ledc_fade_start(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        }
    }
}


void led_fade(){
    ledc_timer_config_t ledc_timer_cfg = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .timer_num = LEDC_TIMER_0,
        .clk_cfg = LEDC_AUTO_CLK,
        .freq_hz = 5000,
        .duty_resolution = LEDC_TIMER_13_BIT,
    };
    ledc_timer_config(&ledc_timer_cfg);

    ledc_channel_config_t ledc_channel = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = LEDC_CHANNEL_0,
        .timer_sel = LEDC_TIMER_0,
        .gpio_num = LED_GPIO_NUM,
        .duty = 0,
        .intr_type = GPIO_INTR_DISABLE,
    };
    ledc_channel_config(&ledc_channel);
    ledc_fade_func_install(0);

    ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 8191, 2000);
    ledc_cbs_t cbs = {
        .fade_cb = ledc_finish_cb,
    };
    ledc_cb_register(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, &cbs, NULL);
    ledc_fade_start(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
}

void run_led_fade_task(){
    ESP_LOGI("TASK", "Run fade task\n");
    ledc_event_handle = xEventGroupCreate();
    led_fade();
    xTaskCreatePinnedToCore(fade_events_listener, "fade events listener", 2048, NULL, 3, NULL, 0);
}
